/**
 * 
 */
package cn.egame.extraction.thread;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Logger;

import cn.egame.common.exception.ExceptionCommonBase;
import cn.egame.common.util.Utils;
import cn.egame.common.web.ExceptionWeb;
import cn.egame.extraction.pojo.EfsInfo;
import cn.egame.extraction.timer.ExtractionStart;
import cn.egame.extraction.util.ConstVar_EFS;
import cn.egame.extraction.util.ExtractionInit;
import cn.egame.extraction.util.FileService;
import cn.egame.interfaces.fl.FileUsedType;
import cn.egame.interfaces.fl.FileUtils;

/**
 * Description 处理线程自启动循环
 * 
 * @ClassName ExtractionThread
 * 
 * @Copyright 炫彩互动
 * 
 * @Project egame.mobile.extraction
 * 
 * @Author yujm
 * 
 * @Create Date 2014-6-5
 * 
 * @Modified by none
 * 
 * @Modified Date
 */

public class ExtractionThreadBak extends Thread {
    private static final Logger logger = Logger.getLogger(ExtractionThreadBak.class);
    private static Logger errorSyncIdLog = Logger.getLogger("errorSyncId");
    // private static int number = 0;
    private static byte[] lock = new byte[0];
    private EfsInfo efsInfo;

    /**
     * 缓冲队列
     */
    // private static LinkedBlockingQueue<Runnable> queue = new
    // LinkedBlockingQueue<Runnable>(ConstVar_EFS.BLOCK_SIZE);
    public ExtractionThreadBak(EfsInfo efsInfo) {
        this.efsInfo = efsInfo;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Thread#run()
     */
    @Override
    public void run() {
        try {
            String localfilePath = null;
            if (efsInfo.getEfs_type().matches("^\\d+$")) {
                int efsTypeNum = Utils.toInt(efsInfo.getEfs_type(), 0);
                try {
                    // 打印队列中的缓冲数量
                    logger.info("########当前队列中缓冲的数量：" + ExtractionStart.queue.size());
                    long start = System.currentTimeMillis();
                    List<String> filePathList = new ArrayList<String>();
                    localfilePath = FileUtils.getFilePath(FileUsedType.lookup(efsTypeNum), efsInfo.getEfs_id(), efsInfo.getFile_name());
                    filePathList.add(localfilePath);
                    // 以下三种图片文件类型需要拉取压缩的多份
                    if (efsTypeNum == FileUsedType.GAME_PHOTO) {
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.GAME_PHOTO_BIG), 
                                efsInfo.getEfs_id(), efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.GAME_PHOTO_MID), 
                                efsInfo.getEfs_id(), efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.GAME_PHOTO_SMALL), 
                            efsInfo.getEfs_id(), efsInfo.getFile_name()));
                    } else if (efsTypeNum == FileUsedType.HEAD_PHOTO) {
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.HEAD_SML), efsInfo.getEfs_id(),
                                efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.HEAD_MID), efsInfo.getEfs_id(),
                                efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.HEAD_BIG), efsInfo.getEfs_id(),
                                efsInfo.getFile_name()));
                    } else if (efsTypeNum == FileUsedType.ALBUM_PHOTO) {
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.ALBUM_PHOTO_SML), efsInfo.getEfs_id(),
                                efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.ALBUM_PHOTO_MID), efsInfo.getEfs_id(),
                                efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.ALBUM_PHOTO_BIG), efsInfo.getEfs_id(),
                                efsInfo.getFile_name()));
                    } else if (efsTypeNum == FileUsedType.GAME_VIEW) {
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.GAME_VIEW_BIG), 
                                efsInfo.getEfs_id(), efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.GAME_VIEW_MID), 
                                efsInfo.getEfs_id(), efsInfo.getFile_name()));
                        filePathList.add(FileUtils.getFilePath(FileUsedType.lookup(FileUsedType.GAME_VIEW_SMALL), 
                                efsInfo.getEfs_id(), efsInfo.getFile_name()));
                    }

                    logger.info("准备拉取id为" + efsInfo.getEfs_id() + "的文件");
                    // 先判断该id对应的文件是否存在
                    boolean exists = FileService.isFilesExists(filePathList);
                    if (exists) {
                        logger.info("id为" + efsInfo.getEfs_id() + "的文件已存在");
                        FileService.fetchOkAndWriteBack(efsInfo);
                        // 防止存储id的文件中id过小,走不到下面的storeIdToFile方法,
                        // 存储id的文件就一直不会更新,所以这边需要调用storeIdToFile方法
                        // 只有从url中拉取的文件id才需要写入max_id文件
                        // if (efsInfo.getType() == EfsInfoFromType.fromUrl) {
                        // FileService.storeIdToFile(efsInfo.getEfs_id() + 1,
                        // ConstVar_EFS.MAX_ID_FILE_PATH ,readMaxId,writeMaxId);
                        // }
                        // continue;
                    } else {
                        // 文件不存在拉取文件
                        for (String filePath : filePathList) {
                            try {
                                int i = FileService.catchFile(1, efsInfo, filePath);
                                localfilePath = filePath;
                                File file = new File(ConstVar_EFS.UPLOAD_ADDRESS + filePath);// TODO
                                long length = FileService.getInputStreamLengthFromUrl(ConstVar_EFS.DNS_HOST + filePath);
                                if (i > ConstVar_EFS.REPEAT_READ_NUM || !file.exists() || file.length() != length) {
                                    logger.error("(i > ConsVar_EFS.REPEAT_READ_NUM) --->" + (i > ConstVar_EFS.REPEAT_READ_NUM));
                                    logger.error("(!file.exists()) --->" + (!file.exists()));
                                    logger.error("(file.length()!=length) --->" + (file.length() != length));
                                    throw new ExceptionCommonBase(-1, "文件拉取失败");
                                }
                            } catch (ExceptionWeb ew) {
                                logger.error(ew);
                                errorSyncIdLog.error("id为" + efsInfo.getEfs_id() + "类型为:" + efsInfo.getEfs_type() + "的文件拉取失败,异常信息为:"
                                        + ew.getMessage() + " 对应的url为:" + ConstVar_EFS.DNS_HOST + filePath);
                                FileService.writeBackToErrorFilePath(ConstVar_EFS.CONNECT_ERROR_IDS_FILE_PATH,
                                        FileService.connectionErrorEfsMode, efsInfo, 1);

                            } catch (Exception e) {
                                logger.error(e);
                                errorSyncIdLog.error("id为" + efsInfo.getEfs_id() + "类型为:" + efsInfo.getEfs_type() + "的文件拉取失败, 对应的url为:"
                                        + ConstVar_EFS.DNS_HOST + filePath);
                                FileService.writeBackToErrorFilePath(ConstVar_EFS.FETCH_ERROR_IDS_FILE_PATH,
                                        FileService.fetchErrorEfsInfosMode, efsInfo, 1);
                            }
                        }

                    }
                    // if(efsInfo.getType() == EfsInfoFromType.fromUrl){
                    // FileService.storeIdToFile(efsInfo.getEfs_id()+1,
                    // ConstVar_EFS.MAX_ID_FILE_PATH,readMaxId,writeMaxId);
                    // }
                    // exists = FileService.isFilesExists(filePathList);
                    // if(exists){
                    // FileService.fetchOkAndWriteBack(efsInfo);
                    // }
                    long end = System.currentTimeMillis();
                    logger.info("###process spend time: " + (end - start) / 1000.0 + "s");
                } catch (Exception e) {
                    errorSyncIdLog.error("id为" + efsInfo.getEfs_id() + "的文件拉取失败, 对应的url为:" + ConstVar_EFS.DNS_HOST + localfilePath);
                    try {
                        FileService.writeBackToErrorFilePath(ConstVar_EFS.FETCH_ERROR_IDS_FILE_PATH, FileService.fetchErrorEfsInfosMode,
                                efsInfo, 1);
                    } catch (ExceptionCommonBase e1) {

                        logger.error(e.getMessage(), e);
                    }
                }
            } else {
                try {
                    logger.info("准备拉取类型为" + efsInfo.getEfs_type() + ",路径为" + ConstVar_EFS.DNS_HOST + efsInfo.getFile_name() + "的文件");
                    // 先判断该id对应的文件是否存在
                    List<String> filePathList = new ArrayList<String>();
                    filePathList.add(efsInfo.getFile_name());
                    boolean exists = FileService.isFilesExists(filePathList);
                    if (exists) {
                        logger.info("类型为" + efsInfo.getEfs_type() + ",路径为" + ConstVar_EFS.UPLOAD_ADDRESS + efsInfo.getFile_name()
                                + "的文件已存在");
                        // continue;
                    }
                    int i = FileService.catchFile(1, efsInfo, efsInfo.getFile_name());
                    File file = new File(ConstVar_EFS.UPLOAD_ADDRESS + efsInfo.getFile_name());
                    long length = FileService.getInputStreamLengthFromUrl(ConstVar_EFS.DNS_HOST + efsInfo.getFile_name());
                    if (i > ConstVar_EFS.REPEAT_READ_NUM || !file.exists() || file.length() != length) {
                        logger.error("(i > ConsVar_EFS.REPEAT_READ_NUM) --->" + (i > ConstVar_EFS.REPEAT_READ_NUM));
                        logger.error("(!file.exists()) --->" + (!file.exists()));
                        logger.error("(file.length()!=length) --->" + (file.length() != length));
                        throw new ExceptionCommonBase(-1, "文件拉取失败");
                    }
                    exists = FileService.isFilesExists(filePathList);
                    if (exists) {
                        FileService.fetchOkAndWriteBack(efsInfo);
                    }
                } catch (ExceptionWeb ew) {
                    errorSyncIdLog.error("类型为:" + efsInfo.getEfs_type() + ",路径为" + ConstVar_EFS.DNS_HOST + efsInfo.getFile_name()
                            + "的文件拉取失败,异常信息为:" + ew.getMessage());
                    try {
                        FileService.writeBackToErrorFilePath(ConstVar_EFS.CONNECT_ERROR_IDS_FILE_PATH, FileService.connectionErrorEfsMode,
                                efsInfo, 1);
                    } catch (ExceptionCommonBase e) {

                        logger.error(e.getMessage(), e);
                    }
                } catch (Exception e) {
                    errorSyncIdLog.error("类型为:" + efsInfo.getEfs_type() + ",路径为" + ConstVar_EFS.DNS_HOST + efsInfo.getFile_name()
                            + "的文件拉取失败");
                    try {
                        FileService.writeBackToErrorFilePath(ConstVar_EFS.FETCH_ERROR_IDS_FILE_PATH, FileService.fetchErrorEfsInfosMode,
                                efsInfo, 1);
                    } catch (ExceptionCommonBase e1) {

                        logger.error(e.getMessage(), e);
                    }
                }
            }

        } catch (Exception e) {
            logger.error("####线程运行异常。。。");
        } finally {
            ExtractionStart.number.incrementAndGet();
            logger.info("### process thread: " + Thread.currentThread().getName() + ",number: " + ExtractionStart.number.get()
                    + ",efsInfoList size: " + ExtractionInit.efsInfoList.size());
        }

    }
}
